import { camelCase, kebabCase, debounce } from 'lodash-es';
import { defineStore } from 'pinia';
import { theme } from 'ant-design-vue';
import { computed, ref, watch } from 'vue';

const COMMON_CONFIG = {
  token: {
    fontSize: 16,
  },
  components: {
    Tree: {
      fontSize: 14,
    },
  },
};

const CONFIG = {
  light: {
    algorithm: theme.defaultAlgorithm,
    token: {
      ...COMMON_CONFIG.token,
      colorBgBase: '#ffffff',
      /* custom */
      colorBgHeader: '#193167',
      // colorBgSideMenu: '#18162C',
      // colorBgSideSubMenu: '#18162C',
      colorBgSideMenu: '#001529',
      colorBgSideSubMenu: '#000c17',
      colorTextReverse: 'rgba(255, 255, 255, 0.88)',
      colorSplitReverse: 'rgba(255, 255, 255, 0.15)',
    },
    components: {
      ...COMMON_CONFIG.components,
    },
  },
  grey: {
    algorithm: theme.defaultAlgorithm,
    token: {
      ...COMMON_CONFIG.token,
    },
    components: {
      ...COMMON_CONFIG.components,
    },
  },
  dark: {
    algorithm: theme.darkAlgorithm,
    token: {
      ...COMMON_CONFIG.token,
      colorBgBase: '#172025',
      /* custom */
      colorBgHeader: '#19384d',
      colorBgSideMenu: '#27363E',
      colorBgSideSubMenu: '#172025',
      colorTextReverse: 'rgba(0, 0, 0, 0.88)',
      colorSplitReverse: 'rgba(255, 255, 255, 0.15)',
    },
    components: {
      ...COMMON_CONFIG.components,
      Tree: {
        controlItemBgActive: '#1890ff',
      },
    },
  },
};

export const useAntdvThemeStore = defineStore('antdv-theme', () => {
  const defaultMode = 'light';
  const mode = ref(defaultMode);
  const themes = ref(CONFIG);
  const { token } = theme.useToken();
  const provider = computed(() => {
    return themes.value[mode.value] || themes.value[defaultMode];
  });
  const variable = computed(() => {
    return Object.assign({}, token.value, provider.value.token);
  });

  function configTheme(mode, options) {
    themes.value[mode] = Object.assign({}, themes.value[mode], options);
  }

  function useTheme(name) {
    if (name && name in themes.value) {
      mode.value = name;
      document.documentElement.setAttribute('data-theme', name);
      document.documentElement.setAttribute('data-vxe-ui-theme', name);
    }
  }

  function useThemeCssVars(vars, el) {
    if (!Array.isArray(vars)) vars = [vars];
    if (!el || el.nodeType !== 1) el = document.documentElement;
    return vars.forEach((name) => {
      let key = camelCase(name.replace(/^--/, ''));
      let val = variable.value[key];
      if (val) {
        if (!/^--/.test(name)) name = '--' + kebabCase(name);
        if (['--border-radius'].includes(name) && /^\d+$/.test(val)) val += 'px';
        el.style.setProperty(name, val);
      }
    });
  }

  function setOtherCssVars() {
    let _map = {
      '--vxe-table-header-background-color': 'colorBgLayout',
      '--vxe-table-body-background-color': 'transparent',
      '--vxe-table-row-striped-background-color': 'colorBgLayout',
      '--vxe-table-row-current-background-color': 'colorFill',
      '--vxe-table-row-hover-background-color': 'colorFill',
      '--vxe-table-row-hover-striped-background-color': 'colorFill',
      '--vxe-table-row-hover-current-background-color': 'colorFill',
      '--w-e-textarea-color': 'colorText',
      '--w-e-textarea-bg-color': 'colorFillQuaternary',
      '--w-e-toolbar-bg-color': 'colorFillQuaternary',
      '--w-e-modal-button-bg-color': 'colorFillQuaternary',
      '--w-e-textarea-border-color': 'colorBorder',
      '--w-e-toolbar-border-color': 'colorBorder',
      '--w-e-modal-button-border-color': 'colorBorder',
    };
    let style = document.documentElement.style;
    for (const key in _map) {
      let val = _map[key];
      style.setProperty(key, variable.value[val] || val);
    }
  }

  watch(
    variable,
    debounce(() => {
      useThemeCssVars([
        'colorBgHeader',
        'colorBgSideMenu',
        'colorBgSideSubMenu',
        'colorBgLayout',
        'colorBgContainer',
        'colorBgElevated',
        'colorText',
        'colorTextReverse',
        'colorTextDisabled',
        'colorPrimary',
        'colorSuccess',
        'colorWarning',
        'colorError',
        'colorSplit',
        'colorSplitReverse',
        'colorBorder',
        'borderRadius',
      ]);
      setOtherCssVars();
    }, 10)
  );

  useTheme(mode.value);

  return { themes, mode, variable, provider, configTheme, useTheme, useThemeCssVars };
});
